<!--
 * @Description: 消息与信号
 * @Author: DHL
 * @Date: 2022-04-18 14:45:52
 * @LastEditors: DHL
 * @LastEditTime: 2022-08-25 13:37:57
-->

<template>
  <div class="process-panel-tab__content">
    <div class="process-panel-tab__content-title">
      <div>
        <svg-icon className="process-icon" iconClass="appStoreFill"></svg-icon>
        <span>消息列表</span>
      </div>
      <el-button type="primary" size="small" @click="handleOpen('message')">
        <svg-icon className="process-icon" iconClass="plus"></svg-icon>
        创建新消息
      </el-button>
    </div>

    <div class="mt10 process-panel-tab__content-table">
      <el-table :data="messageList" size="small" border>
        <el-table-column type="index" label="序号" width="50px" />
        <el-table-column label="消息ID" prop="id" max-width="300px" show-overflow-tooltip />
        <el-table-column label="消息名称" prop="name" max-width="300px" show-overflow-tooltip />
        <el-table-column label="删除" prop="action" width="50px" align="center">
          <template #default="scope">
            <el-button link type="danger" title="删除" @click="handleDelete(scope.row, 'message')">
              <svg-icon className="process-icon" iconClass="delete"></svg-icon>
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <el-divider />

    <div class="process-panel-tab__content-title">
      <div>
        <svg-icon className="process-icon" iconClass="appStoreFill"></svg-icon>
        <span>信号列表</span>
      </div>
      <el-button type="primary" size="small" @click="handleOpen('signal')">
        <svg-icon className="process-icon" iconClass="plus"></svg-icon>
        创建新信号
      </el-button>
    </div>

    <div class="mt10 process-panel-tab__content-table">
      <el-table :data="signalList" size="small" border>
        <el-table-column type="index" label="序号" width="50px" />
        <el-table-column label="信号ID" prop="id" max-width="300px" show-overflow-tooltip />
        <el-table-column label="信号名称" prop="name" max-width="300px" show-overflow-tooltip />
        <el-table-column label="删除" prop="action" width="50px" align="center">
          <template #default="scope">
            <el-button link type="danger" title="删除" @click="handleDelete(scope.row, 'signal')">
              <svg-icon className="process-icon" iconClass="delete"></svg-icon>
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <tw-dialog
      v-model="modelVisible"
      :title="modelConfig.title"
      width="400px"
      :showZoom="false"
      @close="handleClose"
    >
      <el-form ref="dbFormRef" :model="dbForm" label-width="90px">
        <el-form-item :label="modelConfig.idLabel">
          <el-input v-model="dbForm.id" clearable></el-input>
        </el-form-item>
        <el-form-item :label="modelConfig.nameLabel">
          <el-input v-model="dbForm.name" clearable></el-input>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="handleClose()">取 消</el-button>
        <el-button type="primary" @click="handleSubmit()"> 保 存 </el-button>
      </template>
    </tw-dialog>
  </div>
</template>

<script lang="ts">
  export default { name: 'PanelSignalAndMassage' }
</script>

<script setup lang="ts">
  import { ElMessage } from 'element-plus'
  import { assign } from 'lodash-es'
  import { computed, nextTick, onMounted, reactive, ref } from 'vue'
  import { arrayRemoveByPropertyValue } from '/@/utils/twUtils'
  import { useBpmnStore } from '../../store/bpmn'

  //////////////////////////////////////////////////
  // 属性
  //////////////////////////////////////////////////
  const bpmnStore = useBpmnStore()

  const rootElements: any = ref([])

  /**
   * 信号列表
   */
  const signalList: any = ref([])

  /**
   * 消息列表
   */
  const messageList: any = ref([])

  let messageIdMap: any = {}
  let signalIdMap: any = {}

  const modelVisible = ref(false)

  const modelType = ref('')

  const dbForm = reactive({ id: '', name: '' })

  const modelConfig = computed(() => {
    if (modelType.value === 'message') {
      return { title: '创建消息', idLabel: '消息ID', nameLabel: '消息名称' }
    } else {
      return { title: '创建信号', idLabel: '信号ID', nameLabel: '信号名称' }
    }
  })

  //////////////////////////////////////////////////
  // 函数
  //////////////////////////////////////////////////
  function initDataList() {
    rootElements.value = bpmnStore.bpmnModeler?.getDefinitions()?.rootElements

    messageList.value = []
    signalList.value = []

    rootElements.value?.forEach((el: any) => {
      if (el.$type === 'bpmn:Message') {
        messageIdMap[el.id] = true
        messageList.value.push({ ...el })
      }
      if (el.$type === 'bpmn:Signal') {
        signalIdMap[el.id] = true
        signalList.value.push({ ...el })
      }
    })
  }

  function handleOpen(type: string) {
    modelType.value = type
    assign(dbForm, { id: '', name: '' })
    modelVisible.value = true
  }

  function handleClose() {
    modelVisible.value = false
  }

  function handleSubmit() {
    if (modelType.value === 'message') {
      if (messageIdMap[dbForm.id]) {
        return ElMessage.error('该消息已存在，请修改ID后重新保存')
      }
      const messageRef = bpmnStore.moddle.create('bpmn:Message', dbForm)

      rootElements.value.push(messageRef)
    } else {
      if (signalIdMap[dbForm.id]) {
        return ElMessage.error('该信号已存在，请修改ID后重新保存')
      }
      const signalRef = bpmnStore.moddle.create('bpmn:Signal', dbForm)
      rootElements.value.push(signalRef)
    }
    modelVisible.value = false
    initDataList()
  }

  function handleDelete(row: any, type: string) {
    if (type === 'message') {
      bpmnStore.removeRootElementsById('bpmn:Message', row.id)
      arrayRemoveByPropertyValue(messageList.value, 'id', row.id)
      delete messageIdMap[row.id]
    } else {
      bpmnStore.removeRootElementsById('bpmn:Signal', row.id)
      arrayRemoveByPropertyValue(signalList.value, 'id', row.id)
      delete signalIdMap[row.id]
    }
  }

  //////////////////////////////////////////////////
  // 生命周期
  //////////////////////////////////////////////////
  onMounted(() => {
    nextTick(() => {
      initDataList()
    })
  })
</script>
